package com.zxy.ziems.server.production.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.zxy.ziems.server.constant.DateType;
import com.zxy.ziems.server.constant.enums.DictCodeEnum;
import com.zxy.ziems.server.domain.DictItem;
import com.zxy.ziems.server.dto.DateDto;
import com.zxy.ziems.server.mybatis.core.service.ServiceImplX;
import com.zxy.ziems.server.production.mapper.CustXyhCompletercvMapper;
import com.zxy.ziems.server.production.mapper.CustXyhViewMapper;
import com.zxy.ziems.server.production.pojo.dto.CustXyhCompletercvCountDTO;
import com.zxy.ziems.server.production.pojo.entity.CustXyhCompletercvEntity;
import com.zxy.ziems.server.production.service.CustXyhCompletercvService;
import com.zxy.ziems.server.service.DictItemService;
import com.zxy.ziems.server.utils.BusinessExceptionUtil;
import com.zxy.ziems.server.utils.DateUtils;
import com.zxy.ziems.server.vo.ChartVo;
import com.zxy.ziems.server.vo.ChartYAxisVo;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Copyright (C),
 * @ClassName: CustXyhCompletercvServiceImpl
 * @Author: yanzhiwei
 * @Description:
 * @Date: 2024/5/13 15:21
 */
@Service
public class CustXyhCompletercvServiceImpl extends ServiceImplX<CustXyhCompletercvMapper, CustXyhCompletercvEntity>
        implements CustXyhCompletercvService {

    @Autowired
    private CustXyhViewMapper custXyhViewMapper;

    @Autowired
    private CustXyhCompletercvMapper custXyhCompletercvMapper;
    @Autowired
    private DictItemService dictItemService;

    /**
     * 产量统计
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param queryType 查询类型
     * @return
     */
    @Override
    public ChartVo CustXyhCompletercvDataCompareOld(String startDate, String endDate, String queryType) {
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTOList = new ArrayList<>();

        List<DictItem> dictItemList = dictItemService.getByDictCode(DictCodeEnum.MATERIAL_NO.getCode());
        List<String> stringList = dictItemList.stream().map(m -> m.getItemCode()).collect(Collectors.toList());
        //切分 811030-0160-GB301-产品完工
        List<String> materialNoList = new ArrayList<>();
        List<String> productNameList = new ArrayList<>();
        List<String> billTypeList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(stringList)) {
            for (String s : stringList) {
                String[] list = s.split("_");
                if (list.length == 3) {
                    materialNoList.add(list[0]);
                    //productNameList.add(list[1]);
                    billTypeList.add(list[2]);
                }
            }
        }

        if (queryType.equals(DateType.DAY)) {
            queryType = DateType.MONTH;
            custXyhCompletercvCountDTOList = baseMapper.typeMonthCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        } else if (queryType.equals(DateType.MONTH)) {
            queryType = DateType.YEAR;
            custXyhCompletercvCountDTOList = baseMapper.typeYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        } else if (queryType.equals(DateType.YEAR)) {
            queryType = DateType.HIS_YEAR;
            custXyhCompletercvCountDTOList = baseMapper.typeHisYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        }


        //根据查询条件计算起止时间
        DateDto dateDto = DateUtils.dateQueryConvertNo(queryType, startDate, endDate, true);
        //构建x轴
        List<LocalDateTime> list = DateUtils.dateToList(queryType, dateDto.getStartDay(), dateDto.getEndDay());


        return getChartVo(DateUtils.xAxisConvert(queryType, list), custXyhCompletercvCountDTOList);
    }

    /**
     * 产量统计
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param queryType 查询类型
     * @return
     */
    @Override
    public ChartVo CustXyhCompletercvDataCompare(String startDate, String endDate, String queryType) {
        List<DictItem> dictItemList = dictItemService.getByDictCode(DictCodeEnum.MATERIAL_NO.getCode());
        List<String> stringList = dictItemList.stream().map(m -> m.getItemCode()).collect(Collectors.toList());
        //切分 811030-0160-GB301-产品完工
        List<String> materialNoList = new ArrayList<>();
        List<String> productNameList = new ArrayList<>();
        List<String> billTypeList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(stringList)) {
            for (String s : stringList) {
                String[] list = s.split("_");
                if (list.length == 3) {
                    materialNoList.add(list[0]);
                    //productNameList.add(list[1]);
                    billTypeList.add(list[2]);
                }
            }
        }

        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTOList = new ArrayList<>();
        if (queryType.equals(DateType.DAY)) {
            custXyhCompletercvCountDTOList = baseMapper.typeDayCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        } else if (queryType.equals(DateType.MONTH)) {
            custXyhCompletercvCountDTOList = baseMapper.typeMonthCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        } else if (queryType.equals(DateType.YEAR)) {
            custXyhCompletercvCountDTOList = baseMapper.typeYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        } else if (queryType.equals(DateType.HIS_YEAR)) {
            // 如果时间为0，默认查询所有
            if (startDate == null || startDate == "") {
                startDate = DateUtils.getDateStrByQueryType(DateType.HIS_YEAR, baseMapper.getBeginDate());
                endDate = DateUtils.getDateStrByQueryType(DateType.HIS_YEAR, LocalDateTime.now());
            }

            custXyhCompletercvCountDTOList = baseMapper.typeHisYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        }


        //根据查询条件计算起止时间
        DateDto dateDto = DateUtils.dateQueryConvert(queryType, startDate, endDate, true);
        //构建x轴
        List<LocalDateTime> list = DateUtils.dateToList(queryType, dateDto.getStartDay(), dateDto.getEndDay());


        return getChartVo(DateUtils.xAxisConvert(queryType, list), custXyhCompletercvCountDTOList);
    }


    /**
     * 产量统计
     *
     * @return
     */
    @Override
    public ChartVo CustXyhCompletercvDataCompare() {
        List<DictItem> dictItemList = dictItemService.getByDictCode(DictCodeEnum.MATERIAL_NO.getCode());
        List<String> stringList = dictItemList.stream().map(m -> m.getItemCode()).collect(Collectors.toList());
        //切分 811030-0160-GB301-产品完工
        List<String> materialNoList = new ArrayList<>();
        List<String> productNameList = new ArrayList<>();
        List<String> billTypeList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(stringList)) {
            for (String s : stringList) {
                String[] list = s.split("_");
                if (list.length == 3) {
                    materialNoList.add(list[0]);
                    //productNameList.add(list[1]);
                    billTypeList.add(list[2]);
                }
            }
        }

        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTOList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime sameMonthLast1Year = now.withYear(now.getYear() - 1);
//        LocalDateTime sameMonthLast2Year = now.withYear(now.getYear() - 2);


        LocalDateTime start = now.minusMonths(6).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime end = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);


        String date1 = DateUtils.getDateStrByQueryType(DateType.HIS_YEAR, now);
        String date2 = DateUtils.getDateStrByQueryType(DateType.HIS_YEAR, sameMonthLast1Year);
        String startDate = DateUtils.getDateStrByQueryType(DateType.YEAR, start);
        String endDate = DateUtils.getDateStrByQueryType(DateType.YEAR, end);

        // 数据
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTO1List = baseMapper.typeYearCount(DateUtils.getMonthFirst(date1), DateUtils.getYearMonthCurrent(date1), materialNoList, productNameList, billTypeList);
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTO2List = baseMapper.typeYearCount(DateUtils.getMonthFirst(date2), DateUtils.getYearMonthCurrent(date2), materialNoList, productNameList, billTypeList);
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTONowList = baseMapper.typeYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);

        // 处理前两个年度数据
        long sum1 = custXyhCompletercvCountDTO1List.stream().mapToLong(m -> m.getCount()).sum();
        CustXyhCompletercvCountDTO custXyhCompletercvCountDTO1 = new CustXyhCompletercvCountDTO();
        custXyhCompletercvCountDTO1.setDate(date1);
        custXyhCompletercvCountDTO1.setCount(sum1);
        long sum2 = custXyhCompletercvCountDTO2List.stream().mapToLong(m -> m.getCount()).sum();
        CustXyhCompletercvCountDTO custXyhCompletercvCountDTO2 = new CustXyhCompletercvCountDTO();
        custXyhCompletercvCountDTO2.setDate(date2);
        custXyhCompletercvCountDTO2.setCount(sum2);


        custXyhCompletercvCountDTOList.add(custXyhCompletercvCountDTO1);
        custXyhCompletercvCountDTOList.add(custXyhCompletercvCountDTO2);
        custXyhCompletercvCountDTOList.addAll(custXyhCompletercvCountDTONowList);


        List<String> list = DateUtils.xAxisConvert(DateType.YEAR, DateUtils.yearToMonthInt(endDate, 6));

        // 构建X
        List<String> xList = new ArrayList<>();
        xList.add(date2);
        xList.add(date1);
        xList.add(null);
        xList.addAll(list);


        ChartVo chartVo = getChartVo(xList, custXyhCompletercvCountDTOList);

        chartVo.setXAxisList(formatString(xList));
        return chartVo;
    }


    private List<String> formatString(List<String> xList) {
        List<String> strings = new ArrayList<>();
        for (String s : xList) {
            if (StringUtils.isBlank(s)) {
                strings.add("");
                continue;
            }
            if (s.length() <= 4) {
                s = s + ".01~" + DateUtils.getCurrentMonth();
            }
            s = s.substring(2, s.length());
            s = s.replace("-", ".");
            strings.add(s);
        }

        return strings;
    }

    private List<String> formatString1(List<String> xList) {
        List<String> strings = new ArrayList<>();
        for (String s : xList) {
            s = s.substring(5, s.length());
            strings.add(s);
        }

        return strings;
    }


    @Override
    public ChartVo dateMonthRateCount() {
        List<DictItem> dictItemList = dictItemService.getByDictCode(DictCodeEnum.MATERIAL_NO.getCode());
        List<String> stringList = dictItemList.stream().map(m -> m.getItemCode()).collect(Collectors.toList());
        //切分 811030-0160-GB301-产品完工
        List<String> materialNoList = new ArrayList<>();
        List<String> productNameList = new ArrayList<>();
        List<String> billTypeList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(stringList)) {
            for (String s : stringList) {
                String[] list = s.split("_");
                if (list.length == 3) {
                    materialNoList.add(list[0]);
                    //productNameList.add(list[1]);
                    billTypeList.add(list[2]);
                }
            }
        }

        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTOList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime sameMonthLast1Year = now.withYear(now.getYear() - 1);
//        LocalDateTime sameMonthLast2Year = now.withYear(now.getYear() - 2);


        LocalDateTime start = now.minusMonths(6).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime end = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);


        String date1 = DateUtils.getDateStrByQueryType(DateType.HIS_YEAR, now);
        String date2 = DateUtils.getDateStrByQueryType(DateType.HIS_YEAR, sameMonthLast1Year);
        String startDate = DateUtils.getDateStrByQueryType(DateType.YEAR, start);
        String endDate = DateUtils.getDateStrByQueryType(DateType.YEAR, end);

        // 数据
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTO1List = baseMapper.typeYearCount(DateUtils.getMonthFirst(date1), DateUtils.getYearMonthCurrent(date1), materialNoList, productNameList, billTypeList);
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTO2List = baseMapper.typeYearCount(DateUtils.getMonthFirst(date2), DateUtils.getYearMonthCurrent(date2), materialNoList, productNameList, billTypeList);
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTONowList = baseMapper.typeYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);


        // 处理前两个年度数据
        long sum1 = custXyhCompletercvCountDTO1List.stream().mapToLong(m -> m.getCount()).sum();
        CustXyhCompletercvCountDTO custXyhCompletercvCountDTO1 = new CustXyhCompletercvCountDTO();
        custXyhCompletercvCountDTO1.setDate(date1);
        custXyhCompletercvCountDTO1.setCount(sum1);
        long sum2 = custXyhCompletercvCountDTO2List.stream().mapToLong(m -> m.getCount()).sum();
        CustXyhCompletercvCountDTO custXyhCompletercvCountDTO2 = new CustXyhCompletercvCountDTO();
        custXyhCompletercvCountDTO2.setDate(date2);
        custXyhCompletercvCountDTO2.setCount(sum2);


        custXyhCompletercvCountDTOList.add(custXyhCompletercvCountDTO1);
        custXyhCompletercvCountDTOList.add(custXyhCompletercvCountDTO2);
        custXyhCompletercvCountDTOList.addAll(custXyhCompletercvCountDTONowList);


        List<String> list = DateUtils.xAxisConvert(DateType.YEAR, DateUtils.yearToMonthInt(endDate, 6));

        // 构建X
        List<String> xList = new ArrayList<>();
        xList.add(date2);
        xList.add(date1);
        xList.add(null);
        xList.addAll(list);


        ChartVo chartVo = new ChartVo();


        Map<String, Long> map =
                custXyhCompletercvCountDTOList.stream().collect(Collectors.toMap(m -> m.getDate(), m -> m.getCount()));

        List<ChartYAxisVo> chartYList = new ArrayList<>();


        List<BigDecimal> yValueList = new ArrayList<>();
        for (String dateTimeStr : xList) {
            //本周期数据
            setYVal(map, yValueList, dateTimeStr);
        }
//        ChartYAxisVo chartYAxisVo = new ChartYAxisVo();
//        chartYAxisVo.setName("产量");
//        chartYAxisVo.setData(yValueList);
//        chartYAxisVo.setType("bar");
//        chartYList.add(chartYAxisVo);


        // 获取配置设备
        List<DictItem> dictItems = dictItemService.getByDictCode(DictCodeEnum.CROP_TURNOVER_RATE.getCode());
        if (CollectionUtil.isEmpty(dictItems)) {
            throw BusinessExceptionUtil.exception("字典未配置稼动率参数");
        }
        String code = dictItems.get(0).getItemCode();
        BigDecimal codeValue = new BigDecimal(code);

        List<BigDecimal> yValueList1 = new ArrayList<>();
        for (String dateTimeStr : xList) {
            //本周期数据
            setYValRate(map, yValueList1, dateTimeStr, codeValue, true);
        }
        ChartYAxisVo chartYAxisVo1 = new ChartYAxisVo();
        chartYAxisVo1.setName("稼动率");
        chartYAxisVo1.setData(yValueList1);
        chartYAxisVo1.setType("line");
        chartYList.add(chartYAxisVo1);


        chartVo.setYAxisList(chartYList);
        chartVo.setXAxisList(formatString(xList));
        return chartVo;
    }

    /**
     * @param thisMap
     * @param thisYValueList
     * @param dateTimeStr
     * @param codeValue      稼动率参数
     */
    private void setYValRate(Map<String, Long> thisMap, List<BigDecimal> thisYValueList, String dateTimeStr, BigDecimal codeValue, Boolean isMonth) {
        if (StringUtils.isBlank(dateTimeStr)) {
            thisYValueList.add(null);
        } else if (thisMap.containsKey(dateTimeStr)) {
            Long pointDataListByDate = thisMap.get(dateTimeStr);
            if (pointDataListByDate != null) {
                BigDecimal codeValueParam = codeValue;
                if (dateTimeStr.length() <= 4 && isMonth) {
                    codeValueParam = new BigDecimal(DateUtils.getCurrentMonthInt()).multiply(codeValue);
                } else if (dateTimeStr.length() <= 4 && !isMonth) {
                    codeValueParam = new BigDecimal(12).multiply(codeValue);
                } else if (dateTimeStr.length() > 7) {
                    codeValueParam = codeValue.divide(new BigDecimal(30), 2, RoundingMode.HALF_UP);
                }
                thisYValueList.add(kgToT(new BigDecimal(pointDataListByDate)).divide(codeValueParam, 2, RoundingMode.HALF_UP));
            } else {
                thisYValueList.add(BigDecimal.ZERO);
            }
        } else {
            thisYValueList.add(BigDecimal.ZERO);
        }
    }

    @NotNull
    private ChartVo getChartVo(List<String> list, List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTOList) {
        ChartVo chartVo = new ChartVo();
        chartVo.setXAxisList(list);

        Map<String, Long> map =
                custXyhCompletercvCountDTOList.stream().collect(Collectors.toMap(m -> m.getDate(), m -> m.getCount()));

        List<ChartYAxisVo> chartYList = new ArrayList<>();


        List<BigDecimal> yValueList = new ArrayList<>();
        for (String dateTimeStr : chartVo.getXAxisList()) {
            //本周期数据
            setYVal(map, yValueList, dateTimeStr);
        }
        ChartYAxisVo chartYAxisVo = new ChartYAxisVo();
        chartYAxisVo.setName("产量");
        chartYAxisVo.setData(yValueList);
        chartYAxisVo.setType("bar");
        chartYList.add(chartYAxisVo);


        chartVo.setYAxisList(chartYList);
        return chartVo;
    }

    @NotNull
    private ChartVo getChartRateVo(List<String> list, List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTOList, BigDecimal codeValue) {
        ChartVo chartVo = new ChartVo();
        chartVo.setXAxisList(list);

        Map<String, Long> map =
                custXyhCompletercvCountDTOList.stream().collect(Collectors.toMap(m -> m.getDate(), m -> m.getCount()));

        List<ChartYAxisVo> chartYList = new ArrayList<>();


        List<BigDecimal> yValueList = new ArrayList<>();
        for (String dateTimeStr : chartVo.getXAxisList()) {
            //本周期数据
//            setYVal(map, yValueList, dateTimeStr);

            // 如果是当年，计算年的时候用 月稼动率*月份；不是当年=月稼动率*12
            setYValRate(map, yValueList, dateTimeStr, codeValue, DateUtils.isCurrentYear(dateTimeStr));
        }
        ChartYAxisVo chartYAxisVo = new ChartYAxisVo();
        chartYAxisVo.setName("稼动率");
        chartYAxisVo.setData(yValueList);
        chartYAxisVo.setType("bar");
        chartYList.add(chartYAxisVo);


        chartVo.setYAxisList(chartYList);
        return chartVo;
    }


    @Override
    public void synData(LocalDate localDate) {
        List<CustXyhCompletercvEntity> data = custXyhViewMapper.listCompletercvView(localDate);
        data.stream().forEach(x -> x.setId(IdWorker.getIdStr()));
        custXyhCompletercvMapper.deleteAll();
        saveBatch(data);
    }

    @Override
    public ChartVo dateRateCount(String startDate, String endDate, String queryType) {
        List<CustXyhCompletercvCountDTO> custXyhCompletercvCountDTOList = new ArrayList<>();

        List<DictItem> dictItemList = dictItemService.getByDictCode(DictCodeEnum.MATERIAL_NO.getCode());
        List<String> stringList = dictItemList.stream().map(m -> m.getItemCode()).collect(Collectors.toList());
        //切分 811030-0160-GB301-产品完工
        List<String> materialNoList = new ArrayList<>();
        List<String> productNameList = new ArrayList<>();
        List<String> billTypeList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(stringList)) {
            for (String s : stringList) {
                String[] list = s.split("_");
                if (list.length == 3) {
                    materialNoList.add(list[0]);
                    //productNameList.add(list[1]);
                    billTypeList.add(list[2]);
                }
            }
        }

        if (queryType.equals(DateType.DAY)) {
            queryType = DateType.MONTH;
            custXyhCompletercvCountDTOList = baseMapper.typeMonthCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        } else if (queryType.equals(DateType.MONTH)) {
            queryType = DateType.YEAR;
            custXyhCompletercvCountDTOList = baseMapper.typeYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        } else if (queryType.equals(DateType.YEAR)) {
            queryType = DateType.HIS_YEAR;
            custXyhCompletercvCountDTOList = baseMapper.typeHisYearCount(startDate, endDate, materialNoList, productNameList, billTypeList);
        }


        //根据查询条件计算起止时间
        DateDto dateDto = DateUtils.dateQueryConvertNo(queryType, startDate, endDate, true);
        //构建x轴
        List<LocalDateTime> list = DateUtils.dateToList(queryType, dateDto.getStartDay(), dateDto.getEndDay());

// 获取配置设备
        List<DictItem> dictItems = dictItemService.getByDictCode(DictCodeEnum.CROP_TURNOVER_RATE.getCode());
        if (CollectionUtil.isEmpty(dictItems)) {
            throw BusinessExceptionUtil.exception("字典未配置稼动率参数");
        }
        String code = dictItems.get(0).getItemCode();
        BigDecimal codeValue = new BigDecimal(code);


        return getChartRateVo(DateUtils.xAxisConvert(queryType, list), custXyhCompletercvCountDTOList, codeValue);
    }

    public void synData2(LocalDate localDate) {
        List<CustXyhCompletercvEntity> data = custXyhViewMapper.listCompletercvView(localDate);
        data.stream().forEach(x -> x.setId(IdWorker.getIdStr()));
        custXyhCompletercvMapper.deleteAll();
        saveBatch(data);
    }

    private void setYVal(Map<String, Long> thisMap, List<BigDecimal> thisYValueList, String dateTimeStr) {
        if (StringUtils.isBlank(dateTimeStr)) {
            thisYValueList.add(null);
        } else if (thisMap.containsKey(dateTimeStr)) {
            Long pointDataListByDate = thisMap.get(dateTimeStr);
            if (pointDataListByDate != null) {
                thisYValueList.add(kgToT(new BigDecimal(pointDataListByDate)));
            } else {
                thisYValueList.add(BigDecimal.ZERO);
            }
        } else {
            thisYValueList.add(BigDecimal.ZERO);
        }
    }


    /**
     * 千克转吨
     *
     * @param kg
     * @return
     */
    private BigDecimal kgToT(BigDecimal kg) {
        return kg.divide(new BigDecimal(1000), 1, RoundingMode.HALF_UP);
    }

}
